﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PaymentHelper.Core.Extension;
using System.Web.Routing;
using System.Web.Mvc;
using System.Web;
using System.Diagnostics;
using System.Collections;
using PaymentHelper.Core;
using PaymentHelper.Core.CommonUtils;

namespace PaymentHelper.Methods.NganLuong
{
    public class NganLuongProcessor : BaseExtension, IPaymentMethod
    {
        public bool SupportCapture
        {
            get { return false; }
        }

        public bool SupportRefund
        {
            get { return false; }
        }

        public bool SupportVoid
        {
            get { return false; }
        }

        public PaymentMethodType PaymentMethodType
        {
            get { return PaymentHelper.PaymentMethodType.Redirection; }
        }

        public decimal GetHandlingFee()
        {
            return GetSetting("HandlingFee");
        }

        public void ProcessPayment(ProcessPaymentRequest processPaymentRequest)
        {
            string merchant_site_code = GetSetting("MerchantSiteCode");
            string nganluong_site = GetSetting("UseSandbox") == true ? GetSetting("SandboxURL") : GetSetting("NganLuongURL");

            string return_url = PHUtility.GetSiteUrl() + GetSetting("ReturnURL");
            string receiver = GetSetting("Email");
            string transaction_info = GetTransactionInfoFromOrder(processPaymentRequest.Order);
            string order_code = processPaymentRequest.Order.OrderId;
            string price = Math.Round(processPaymentRequest.Order.OrderTotal, 2).ToString();
            string secure_pass = GetSetting("SecurePass");

            string urlRedirect = BuildUrlCheckout(nganluong_site, merchant_site_code, return_url, receiver, transaction_info, order_code, price, secure_pass);

            HttpContext.Current.Response.Redirect(urlRedirect);
        }

        public CapturePaymentResult Capture(CapturePaymentRequest capturePaymentRequest)
        {
            CapturePaymentResult result = new CapturePaymentResult();
            result.AddError("Captured method not supported !");
            result.PaymentStatus = Core.RelatedObject.PaymentStatus.Canceled;
            result.Success = false;

            return result;
        }

        public RefundPaymentResult Refund(RefundPaymentRequest refundPaymentRequest)
        {
            RefundPaymentResult result = new RefundPaymentResult();
            result.AddError("Refund method not supported !");
            result.PaymentStatus = Core.RelatedObject.PaymentStatus.Canceled;
            result.Success = false;

            return result;
        }

        public VoidPaymentResult Void(VoidPaymentRequest voidPaymentRequest)
        {
            VoidPaymentResult result = new VoidPaymentResult();
            result.AddError("Void method not supported !");
            result.PaymentStatus = Core.RelatedObject.PaymentStatus.Canceled;
            result.Success = false;

            return result;
        }

        public void GetConfigurationRoute(out string actionName, out string controllerName, out System.Web.Routing.RouteValueDictionary routeValues)
        {
            actionName = "Configure";
            controllerName = "NganLuong";
            routeValues = new RouteValueDictionary();
            routeValues.Add("Namespaces", "PaymentHelper.Methods.NganLuong.Controllers");
            routeValues.Add("area", null);
        }

        public void GetPaymentInfoRoute(out string actionName, out string controllerName, out System.Web.Routing.RouteValueDictionary routeValues)
        {
            actionName = "PaymentInfo";
            controllerName = "NganLuong";
            routeValues = new RouteValueDictionary();
            routeValues.Add("Namespaces", "PaymentHelper.Methods.NganLuong.Controllers");
            routeValues.Add("area", null);
        }

        public void RegisterRoutes(System.Web.Routing.RouteCollection routes)
        {
            routes.MapRoute(
                "NganLuong.PaymentInfo",
                "Methods/NganLuong/PaymentInfo",
                new { controller = "NganLuong", action = "PaymentInfo" },
                new[] { "PaymentHelper.Methods.NganLuong.Controllers" }
                );

            routes.MapRoute(
                "NganLuong.Configure",
                "Methods/NganLuong/Configure",
                new { controller = "NganLuong", action = "PaymentInfo" },
                new[] { "PaymentHelper.Methods.NganLuong.Controllers" }
                );

            routes.MapRoute(
                "NganLuong.Complete",
                "Methods/NganLuong/Complete",
                new { controller = "NganLuong", action = "Complete" },
                new[] { "PaymentHelper.Methods.NganLuong.Controllers" }
                );
        }

        public void GetPaymentInfo(Core.Order orderCurrent, FormCollection collection)
        {
        }

        public PaymentHelper.Core.MVCUtils.PaymentHelperController GetControllerType()
        {
            return new NganLuong.Controllers.NganLuongController();
        }

        public bool AcceptCurrency(string currencyCode)
        {
            if (string.IsNullOrEmpty(currencyCode))
                return false;

            string currencySetting = GetSetting("CurrencyAccepted");

            if (string.IsNullOrEmpty(currencySetting))
                return false;

            var listCurrency = currencySetting.SplitToListString(',');
            return listCurrency.Contains(currencyCode);
        }

        private string GetTransactionInfoFromOrder(Order order)
        {
            if (order.ListOrderItem == null || order.ListOrderItem.Count == 0)
                return "";
            
            StringBuilder builder = new StringBuilder();
            foreach (var item in order.ListOrderItem)
            {
                builder.AppendFormat("{0} ({1}*{2}), ", item.Name, item.Quantiy, item.Price);
            }

            return order.OrderId;
        }

        private string BuildUrlCheckout(string nganluong_url, string merchant_site_code, string return_url, string receiver, string transaction_info, string order_code, string price, string secure_pass)
        {
            if (nganluong_url.IndexOf("?") == -1)
            {
                nganluong_url += "?";
            }
            else if (nganluong_url.Substring(nganluong_url.Length - 1, 1) != "?" && nganluong_url.IndexOf("&") == -1)
            {
                nganluong_url += "&";
            }

            string secure_code = string.Empty;
            secure_code += merchant_site_code;
            secure_code += " " + HttpUtility.UrlEncode(return_url).ToLower();
            secure_code += " " + receiver;
            secure_code += " " + HttpUtility.UrlEncode(transaction_info);
            secure_code += " " + order_code;
            secure_code += " " + price;
            secure_code += " " + secure_pass;

            Hashtable ht = new Hashtable();
            ht.Add("merchant_site_code", merchant_site_code);
            ht.Add("return_url", HttpUtility.UrlEncode(return_url).ToLower());
            ht.Add("receiver", receiver);
            ht.Add("transaction_info", HttpUtility.UrlEncode(transaction_info));
            ht.Add("order_code", order_code);
            ht.Add("price", price);
            ht.Add("secure_code", PHUtility.MD5(secure_code));

            string urlTemp = string.Empty;
            var en = ht.GetEnumerator();

            while (en.MoveNext())
            {
                if (urlTemp == "")
                    urlTemp += en.Key.ToString() + "=" + en.Value.ToString();
                else
                    urlTemp += "&" + en.Key.ToString() + "=" + en.Value.ToString();
            }

            return nganluong_url + urlTemp;
        }

        public bool VerifyPaymentUrl(string transaction_info, string order_code, string price, string payment_id, string payment_type, string error_text, string secure_code)
        {
            //Tạo mã xác thực
            String str = "";

            str += " " + transaction_info;
            str += " " + order_code;
            str += " " + price;
            str += " " + payment_id;
            str += " " + payment_type;
            str += " " + error_text;
            str += " " + GetSetting("MerchantSiteCode");
            str += " " + GetSetting("SecurePass");

            // Mã hóa các tham số
            String verify_secure_code = PHUtility.MD5(str);

            // So sánh xác thực 
            return (verify_secure_code.Equals(secure_code));
        }

    }
}
